package com.example.demo.service;

import com.example.demo.config.MinioPro;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

@Slf4j
@Service
public class MinioServiceImpl implements MinioService {

    @Resource
    private MinioPro minioPro;

    @Autowired
    private MinioClient minioClient;

    /**
     * base64编码的图片上传
     */
    @Override
    public String upload(byte[] base64Str) {
        //oss是前端传来的base64对象，第一行代码将获取对象中的base64字符串
        try {
            InputStream byteArrayInputStream = new ByteArrayInputStream(base64Str);

            boolean bucketExists = minioClient.bucketExists(minioPro.getBucketName());
            if (!bucketExists) {
                minioClient.makeBucket(minioPro.getBucketName());
            }
            // 生成文件名称
            String nameSuffix = UUID.randomUUID().toString() + ".jpg";
            // 上传配置
            PutObjectOptions options = new PutObjectOptions(byteArrayInputStream.available(), PutObjectOptions.MIN_MULTIPART_SIZE);
            options.setContentType("image/jpg");

            minioClient.putObject(minioPro.getBucketName(), nameSuffix, byteArrayInputStream, options);
            return nameSuffix;
        } catch (Exception e) {
            log.error("上传文件失败", e.getMessage());
            return "上传文件失败";
        }
    }

    /**
     * 删除文件
     */
    @Override
    public String delete(String fileName) {
        try {
            minioClient.removeObject(minioPro.getBucketName(), fileName);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return "删除成功";
    }

    /**
     * 获取文件url预览
     */
    @Override
    public String getFileUrl(String objectName) {
        try {
            return minioClient.getObjectUrl(minioPro.getBucketName(), objectName);
        } catch (ErrorResponseException e) {
            throw new RuntimeException(e);
        } catch (InsufficientDataException e) {
            throw new RuntimeException(e);
        } catch (InternalException e) {
            throw new RuntimeException(e);
        } catch (InvalidBucketNameException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        } catch (InvalidResponseException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (XmlParserException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 下载获取文件流
     */
    @Override
    public byte[] download(String objectName) throws IOException {
        InputStream uploadFile = null;
        try {
            uploadFile = minioClient.getObject(minioPro.getBucketName(), objectName);
        } catch (ErrorResponseException e) {
            throw new RuntimeException(e);
        } catch (InsufficientDataException e) {
            throw new RuntimeException(e);
        } catch (InternalException e) {
            throw new RuntimeException(e);
        } catch (InvalidBucketNameException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        } catch (InvalidResponseException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (XmlParserException e) {
            throw new RuntimeException(e);
        }
        //流转字节码数组
        //byte[] bytes = uploadFile.readAllBytes();\
        //return bytes;
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[16384];
        while ((nRead = uploadFile.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }
        return buffer.toByteArray();
    }
}
